package com.gcsoftware.gateway.GWImpl.xml;

import com.gcsoftware.gateway.GWImpl.GwAccessControl;
import com.gcsoftware.gateway.GWImpl.basics.dataProtection;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created by yinpeng on 18/1/25.
 */
public class xmlDataProtectionWithSax implements dataProtection
{
    private static final Logger log = LoggerFactory.getLogger(xmlDataProtectionWithSax.class);
    private  Map<String ,Object> argsMap;

    public void setArgMap( Map<String ,Object> argsMap) {
        this.argsMap = argsMap;
    }


    private void getProtectionWithSax(Element e ,String charSet,Map<String, Object> rbacMap)
    {
        if (rbacMap.containsKey(e.getName())) {
            if (StringUtils.isNotBlank(rbacMap.get(e.getName()).toString()) && !"null".equals(rbacMap.get(e.getName()).toString().toLowerCase())) {
                e.setText(rbacMap.get(e.getName()).toString());
            }
        } else if (rbacMap.containsKey(e.getParent().getName())) {
            if (rbacMap.get(e.getParent().getName()) instanceof HashMap) {
                getProtectionWithSax(e,charSet, (Map<String, Object>) rbacMap.get(e.getParent().getName()));
            }
        }

    }

    public String protectExecute(String context)
    {
        return protectExecute(context,"UTF-8");
    }
    public String protectExecute(String context , String charSet, Map<String , Object> rbacMap)
    {
        String masker = null;
        try
        {
            SAXReader reader = new SAXReader();

            reader.setDefaultHandler(new ElementHandler(){
                public void onEnd(ElementPath ep) {
                    Element e = ep.getCurrent(); //获得当前节点

                    if (StringUtils.isNotBlank(e.getText()) ) {
                        if (e.getText().startsWith("<?xml")){
                            log.debug("Element text start as xml.");
                            try {
                                e.setText(protectExecute(e.getText(), charSet, rbacMap));
                            } catch (Exception ex) {
                                log.error(ex.getMessage(), ex);
                            }
                        } else{
                            getProtectionWithSax(e, charSet, rbacMap);
                        }
                    }

                }
                public void onStart(ElementPath arg0) {
                }
            });
            Document doc = reader.read(new ByteArrayInputStream(context.getBytes(charSet)));

            masker = doc.asXML();

            log.info("[{}][{}][{}][{}][{}][{}][{}][{}][{}][{}]", argsMap.get("sourceIp"),argsMap.get("destinationIp"),argsMap.get("targetMethod"),argsMap.get("appId"),argsMap.get("appName"), argsMap.get("token"),argsMap.get("roleId"), argsMap.get("roleName"),argsMap.get("senstiveIds"),argsMap.get("senstiveNames"));
        }
        catch (Exception e)
        {
            e.printStackTrace();
            //return context;
        }

        return masker;
    }
    public String protectExecute(String context , String charSet)
    {
        Map<String, Object>rbacMap = GwAccessControl.getAccessItemMap((String) argsMap.get("roleId"),(String)argsMap.get("endPoint"),(String)argsMap.get("targetMethod"),(String)argsMap.get("serviceId"));
        return protectExecute(context,charSet,rbacMap);
    }


}
